package cn.tedu.v1;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * 聊天室---功能: 客户端链接服务器端---写出文本   Version 1
 *
 * 聊天室---功能: 客户端链接服务器端:并且发送文本  Version 1.1
 *
 * IO流操作---客户端、服务器端【存在Socket类】
 * 调用Socket中: 获取输入流、输出流
 *              getInputStream()  获取由套接字传入输入流【低级流】
 *              getOutputStream() 获取由套接字传入输出流【低级流】
 *
 * 网络通讯     +IO流
 * Socket套接字  + 文本传输
 *
 * 网络通讯遵循两种原则:
 * C/S架构: Client/Server  客户端/服务器 早期软件应用【手机: 应用商店下载操作】
 * JavaSE 桌面型软件  【并不擅长】
 *
 * B/S架构
 * Browser/Server 浏览器端/服务器 中期软件应用【HTTP协议: 后台逻辑网站】
 * JavaEE 浏览器打开网址【软件--擅长】
 * JavaSE 逻辑  + WEB 前台  + Mysql数据库
 *
 * C/S架构实现聊天室软件
 * Client  客户端 对象    Socket对象 【具备网络通讯所有规则】
 * 【套接字: 网络通讯类】
 * 包位置: java.net
 * Socket对象
 * 客户端开发步骤:
 * 1.定义私有属性: Socket【全局属性: 网络通讯类所有方法以及属性，本类所使用】
 * 2.创建构造器: 实例化Socket对象【传入参数: IP,端口】
 * 3.创建方法start(): IO流
 * 4.构建一个主方法: 创建Client对象并且启动start方法
 *
 * -----------------------------------------------------------------
 * Server  服务器 对象    ServerSocket对象 【具备网络通讯所有规则】 TCP协议
 *
 * 以上两个对象底层传输协议: TCP协议--发送数据【商务:电商、后台...】
 *            TCP协议:可靠性比较好的协议，传输数据效率低，基于字节流
 *                       UDP协议---发送数据【游戏】
 *            UDP协议: 不可靠协议，传输数据效率高，基于数据包
 */
public class Client {
    //1.定义私有属性: Socket网络通讯类
    private Socket socket;   //+ public  - private  // protected #
    //2.创建一个构造器: 创建Socket对象: 传入: IP+端口
    /**
     * 客户端Socket对象
     * 构造器new Socket("传入IP",端口: 数值)
     * 通过 window+r  cmd ipconfig --IVP 4   IP号
     * 使用本地IP地址: localhost  |  127.0.0.1
     *  192.168.100.198
     * 端口: 用来表示计算机上软件大门，每个软件都会有端口号
     *      端口号表示形式: 4位以内的数值
     *      端口号: 6666
     */
    //创建空参构造器
    public Client() {
        try {
            socket=new Socket("127.0.0.1",6666);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //3.创建start方法: 逻辑---IO流--写出  【读入: 参考服务器端操作】
    public void start(){
        //5.从套接字【网络编程类: 手机】
        OutputStream os= null;  //低级流 负责写出


        /*//【拓展1--从socket获取低级流--读入】
        InputStream is=null;*/

        try {
            os = socket.getOutputStream();

           /* //【拓展1--从socket获取低级流--读入】
            is=socket.getInputStream();*/

        } catch (IOException e) {
            e.printStackTrace();
        }
        //套高级流---传输字符串---①转换流---目的:指定字符集
        OutputStreamWriter osw= null;
        try {
            //套高级流---传输字符串---①转换流---目的:指定字符集
            osw = new OutputStreamWriter(os,"UTF8");

           /* //【拓展2--低级流---读入---传字符串: ①转换流 目的: 指定字符集】
            InputStreamReader isr=new InputStreamReader(is,"UTF8");*/

            //套高级流---②缓冲流---目的:加速文字传输  【坑】
            BufferedWriter bw=new BufferedWriter(osw);

            /*//【拓展3--缓冲流  目的: 加速文字传输】
            BufferedReader br=new BufferedReader(isr);*/

            //套高级流---③字符输出流---目的:输出一行文本 【坑: 缓冲区: 内部有数据，即时显示】
            PrintWriter pw=new PrintWriter(bw,true); //autoFlush: 自动刷新

            /*//【拓展4--- 一直读入服务器端发来的文本】
            String str=null;
            //一直: while(true){}  |  str=br.readLine()
            //服务器端发: 一行文本  |  客户端收: 一行文本
            while (true){
                System.out.println("服务器端发来的文本: "+str);
            }*/


            //6.从控制台一直说话
            System.out.println("请服务器端说话: ");
            Scanner input=new Scanner(System.in);   //卡主，等待用户输入
            String line=null;  //6.1变量目的: 保存客户端每次说话内容
            while (true){ //死循环，一直说话
                //所说的每一句话保存给line
                line= input.nextLine(); //从控制台输入对应文本
                pw.println(line);
                System.out.println("写出成功~~~");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }finally {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                osw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //4.构建主方法
    public static void main(String[] args) {
        //客户端对象创建
        Client client=new Client();
        client.start();
    }
}
